import SimpleHTTPServer, SocketServer
import urlparse
from utils import lazytype
from Queue import Queue
import os
import thread

# Use the standard logging facility
import logging
logger = logging.getLogger(__name__)

PORTS = [8765, 8766, 8767, 8768, 8769, 8770]

class Dispatcher(object):
    """
    Simple function call dispatcher.
   
    Helper class to dispatch Lib-Ray function calls from the server without messing with the server
    class too much.
    """
    def __init__(self):
        self.functionmap = {}
        self.queue = Queue()
   
    def dispatch(self, funcname, arg):
        logger.debug("Dispatching - %s(%s)" % (funcname, str(arg)))
        if funcname in self.functionmap:
            self.functionmap[funcname](arg)
        else:
            logger.debug("Dispatcher received unknown function: %s" % funcname)

    def register(self, funcname, function):
        self.functionmap[funcname]=function
        
    def update(self):
        while not self.queue.empty():
            call, arg = self.queue.get()
            self.dispatch(call, arg)
      
dispatcher = Dispatcher()

class LibRayHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def do_GET(self):
        """
        Serve GET requet, intercepting and dispatching GET parameters.
        """
        # Parse query data & params to find out what was passed
        parsedParams = urlparse.urlparse(self.path)
        queryParsed = urlparse.parse_qs(parsedParams.query)
        if len(queryParsed) > 0:
            self._dispatch(queryParsed)  
            
        # Default to serve up a local file 
        #
        # BUG? I think this is not quite the right thing to do if we get
        #      parameters. We might need to redirect the browser to the
        #      unadorned URL or else report a successful call or something.
        #
        #      The symptom is that my browser tries to reload with a '/'
        #      appended.
        #
        SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
       
    def _dispatch(self, calls):
        """
        Examine passed parameters and dispatch calls accordingly.
        """
        for call in calls:
            args = calls[call]
            for arg in args:
              if len(arg)>0 and arg[-1]=='/': # BUG? Workaround for the above problem.
                logger.debug("Throwing out extraneous '/' character")
                arg = arg[:-1]                #      Throw out the extra '/'
              if not dispatcher.queue.full():
                dispatcher.queue.put((call, arg))
                
for PORT in PORTS:
    try:
        httpd = SocketServer.TCPServer(("", PORT), LibRayHandler)
        break
    except:
        pass

def start_server_thread(quit_function):
    logger.info("Lib-Ray server operating on port %d" % PORT)
    thread.start_new_thread(httpd.serve_forever, ())
    return PORT
    
def kill_server_thread():
    httpd.shutdown()

   